package com.beg.cant.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.beg.cant.dto.PageRequest;
import com.beg.cant.dto.PageResponse;
import com.beg.cant.entity.Order;
import com.beg.cant.entity.ShopSettings;
import com.beg.cant.entity.User;
import com.beg.cant.entity.Withdraw;
import com.beg.cant.mapper.OrderMapper;
import com.beg.cant.mapper.UserMapper;
import com.beg.cant.service.OrderService;
import com.beg.cant.service.ShopSettingsService;
import com.beg.cant.service.WithdrawService;
import com.beg.cant.vo.MonthlyStatisticsVO;
import com.beg.cant.vo.OrderStatisticsVO;
import com.beg.cant.vo.WithdrawStatisticsVO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.nio.file.WatchService;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

@Service
@RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    private final OrderMapper orderMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private ShopSettingsService shopSettingsService;
    @Autowired
    private WithdrawService withdrawService;

    /**
     * 支付成功修改订单信息
     *
     * @param code
     */
    @Override
    public void paySuccess(String code) {
        ShopSettings settings = shopSettingsService.getSettings(Long.valueOf(1));
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Order::getOutTradeNo,code);
        List<Order> orders = orderMapper.selectList(queryWrapper);
        LambdaUpdateWrapper<Order> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Order::getOutTradeNo,code).set(Order::getStatus,1).set(Order::getFee,settings.getDiscountRate()*orders.get(0).getAmount());
        orderMapper.update(wrapper);
        // 假设 userMapper 已经被正确注入
        User currentUser = userMapper.selectById(orders.get(0).getUserId());

        if (currentUser != null) {
            // 计算新的 total
            Double newTotal = currentUser.getTotal() == null ? settings.getDiscountRate()*orders.get(0).getAmount() :
                    currentUser.getTotal()+settings.getDiscountRate()*orders.get(0).getAmount();

            // 使用建造者模式创建一个新的 User 对象，并设置 id 和 新的 total
            User updatedUser = User.builder()
                    .id(orders.get(0).getUserId())
                    .total(newTotal)
                    .build();

            // 更新数据库中的用户信息
            userMapper.updateById(updatedUser);
        } else {
            // 处理用户不存在的情况
            throw new RuntimeException("User not found");
        }
    }

    /**
     * 创建支付信息
     *
     * @param order
     */
    @Override
    public void createOrder(Order order) {
        orderMapper.insert(order);
    }

    @Override
    public PageResponse<Order> getOrderList(PageRequest pageRequest) {
        // 创建分页对象
        Page<Order> page = new Page<>(pageRequest.getPageNum(), pageRequest.getPageSize());
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        
        // 添加时间范围筛选
        if (pageRequest.getStartTime() != null) {
            wrapper.ge(Order::getCreatedAt, pageRequest.getStartTime());
        }
        if (pageRequest.getEndTime() != null) {
            wrapper.le(Order::getCreatedAt, pageRequest.getEndTime());
        }
        // 添加code筛选
        if (pageRequest.getCode()!=null){
            wrapper.eq(Order::getUserId,pageRequest.getCode());
        }
        // 添加状态筛选
        if (pageRequest.getState()!=null){
            wrapper.eq(Order::getStatus,pageRequest.getState());
        }
        wrapper.orderByAsc(Order::getAmount).orderByAsc(Order::getCreatedAt);
        // 执行分页查询，按创建时间倒序排序
        IPage<Order> orderPage = orderMapper.selectPage(page, wrapper);
        
        // 构建分页响应
        return PageResponse.of(orderPage.getRecords(), orderPage.getTotal(), pageRequest);
    }

    @Override
    public OrderStatisticsVO getCurrentStatistics() {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime startOfToday = now.toLocalDate().atStartOfDay();
        LocalDateTime startOfMonth = now.withDayOfMonth(1).toLocalDate().atStartOfDay();
        
        LambdaQueryWrapper<Order> todayWrapper = new LambdaQueryWrapper<>();
        todayWrapper.ge(Order::getCreatedAt, startOfToday)
                   .le(Order::getCreatedAt, now)
                   .eq(Order::getStatus, 1);
        
        LambdaQueryWrapper<Order> monthWrapper = new LambdaQueryWrapper<>();
        monthWrapper.ge(Order::getCreatedAt, startOfMonth)
                   .le(Order::getCreatedAt, now)
                   .eq(Order::getStatus, 1);
        
        Double todayIncome = orderMapper.selectList(todayWrapper).stream()
                .mapToDouble(Order::getAmount)
                .sum();
        
        Double monthIncome = orderMapper.selectList(monthWrapper).stream()
                .mapToDouble(Order::getAmount)
                .sum();
        WithdrawStatisticsVO withdrawStatistics = withdrawService.getWithdrawStatistics();
        return OrderStatisticsVO.builder()
                .todayIncome(todayIncome)
                .todayTotal(withdrawStatistics.getTodayAmount())
                .monthIncome(monthIncome)
                .monthAmount(withdrawStatistics.getTodayAmount())
                .build();
    }

    @Override
    public List<MonthlyStatisticsVO> getMonthlyStatistics() {
        LocalDateTime now = LocalDateTime.now();
        List<MonthlyStatisticsVO> statistics = new ArrayList<>();
        
        for (int i = 0; i < 4; i++) {
            LocalDateTime startOfMonth = now.minusMonths(i).withDayOfMonth(1).toLocalDate().atStartOfDay();
            LocalDateTime endOfMonth = startOfMonth.plusMonths(1).minusSeconds(1);
            LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
            wrapper.ge(Order::getCreatedAt, startOfMonth)
                   .le(Order::getCreatedAt, endOfMonth)
                   .eq(Order::getStatus, 1);
            
            Double monthIncome = orderMapper.selectList(wrapper).stream()
                    .mapToDouble(Order::getAmount)
                    .sum();

            statistics.add(MonthlyStatisticsVO.builder()
                    .month(startOfMonth.format(DateTimeFormatter.ofPattern("yyyy-MM")))
                    .income(monthIncome)
                    .withdraw(withdrawService.getWithdrawStatistics().getMonthAmount())
                    .build());
        }
        
        return statistics;
    }
}
